wayland: Don't allocate a full size SHM buffer when drawing using OpenGL
authorJonas Ådahl <jadahl@gmail.com>
Tue, 24 Feb 2015 10:10:07 +0000 (18:10 +0800)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 25 Feb 2015 01:22:03 +0000 (20:22 -0500)
Before this patch, we'd always allocate a full size SHM buffer via
the wl_shm_pool, even though it would never be used. Instead allocate a
logical 1x1 cairo image surface.

https://bugzilla.gnome.org/show_bug.cgi?id=745076

gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkprivate-wayland.h
gdk/wayland/gdkwindow-wayland.c

index 0be9ab6965847268cfeb0305236853cb42835356..46c3cc35c80aac265fd5b3218a1ad6d18e98398b 100644 (file)
@@ -834,6 +834,12 @@ _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface)
   return data->busy;
 }
 
+gboolean
+_gdk_wayland_is_shm_surface (cairo_surface_t *surface)
+{
+  return cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key) != NULL;
+}
+
 GdkWaylandSelection *
 gdk_wayland_display_get_selection (GdkDisplay *display)
 {
index adfff19fabe0859a4448c9614eacda3a47316b79..8a97df0828a839e9ec230271f579cf04861bef95 100644 (file)
@@ -219,6 +219,7 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di
 struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
 void _gdk_wayland_shm_surface_set_busy (cairo_surface_t *surface);
 gboolean _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface);
+gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface);
 
 GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display);
 GdkWaylandSelection * gdk_wayland_selection_new (void);
index b5f048afcd6dbfec52c0af0b688a4ae29ad5ae61..23d6d08ffd1bf27a0e12f380d77d47020698ae0f 100644 (file)
@@ -393,6 +393,8 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
   if (!impl->pending_commit)
     return;
 
+  g_assert (_gdk_wayland_is_shm_surface (impl->cairo_surface));
+
   impl->pending_commit = FALSE;
   impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
 
@@ -522,6 +524,8 @@ gdk_wayland_window_attach_image (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  g_assert (_gdk_wayland_is_shm_surface (impl->cairo_surface));
+
   /* Attach this new buffer to the surface */
   wl_surface_attach (impl->surface,
                      _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface),
@@ -539,7 +543,21 @@ static void
 gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-  if (!impl->cairo_surface)
+
+  /* If we are drawing using OpenGL then we only need a logical 1x1 surface. */
+  if (impl->egl_window)
+    {
+      if (impl->cairo_surface &&
+          _gdk_wayland_is_shm_surface (impl->cairo_surface))
+        cairo_surface_destroy (impl->cairo_surface);
+
+      impl->cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                        impl->scale,
+                                                        impl->scale);
+      cairo_surface_set_device_scale (impl->cairo_surface,
+                                      impl->scale, impl->scale);
+    }
+  else if (!impl->cairo_surface)
     {
       GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
 
@@ -582,7 +600,10 @@ gdk_window_impl_wayland_begin_paint (GdkWindow *window)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
   gdk_wayland_window_ensure_cairo_surface (window);
-  return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface);
+  if (_gdk_wayland_is_shm_surface (impl->cairo_surface))
+    return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface);
+  else
+    return FALSE;
 }
 
 static void